package java_chapter;
import java.util.Arrays;
import java.util.Scanner;
import java.util.regex.Pattern;
import java.util.regex.Matcher;

/**
 * 第5章核心知识点演示 - 数组、字符串与正则表达式
 *
 * 涵盖知识点：
 * 5.1 数组 - 一维数组、二维数组、数组操作
 * 5.2 字符串 - String类操作、StringBuilder使用
 * 5.3 正则表达式 - Pattern、Matcher、常用验证
 *
 * @author 学习者
 */
public class Chapter5 {

    // =========================== 5.1 数组相关 ===========================

    // 一维数组 - 存储学生姓名
    private static String[] studentNames = new String[10];

    // 一维数组 - 存储学生成绩
    private static double[] studentScores = new double[10];

    // 二维数组 - 存储三门课程成绩（语文、数学、英语）
    private static double[][] subjectScores = new double[10][3];

    // 课程名称常量数组
    private static final String[] SUBJECTS = {"语文", "数学", "英语"};

    // 当前学生数量
    private static int currentCount = 0;

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);

        System.out.println("========== 第5章知识点演示系统 ==========");

        while (true) {
            displayMenu();
            System.out.print("请选择功能（1-5）：");
            String choice = scanner.nextLine();

            switch (choice) {
                case "1":
                    arrayDemo();                    // 数组操作演示
                    break;
                case "2":
                    stringDemo();                   // 字符串操作演示
                    break;
                case "3":
                    regexDemo(scanner);             // 正则表达式演示
                    break;
                case "4":
                    comprehensiveDemo(scanner);     // 综合应用演示
                    break;
                case "5":
                    System.out.println("程序结束，感谢使用！");
                    scanner.close();
                    return;
                default:
                    System.out.println("无效输入，请重新选择！");
            }

            System.out.println("\n按回车键继续...");
            try { System.in.read(); } catch (Exception e) {}
        }
    }

    /**
     * 显示主菜单
     */
    private static void displayMenu() {
        System.out.println("\n========== 主菜单 ==========");
        System.out.println("1. 数组操作演示");
        System.out.println("2. 字符串操作演示");
        System.out.println("3. 正则表达式演示");
        System.out.println("4. 综合应用演示");
        System.out.println("5. 退出系统");
        System.out.println("===========================");
    }

    /**
     * 5.1 数组操作演示 - 创建、初始化、遍历、排序
     */
    private static void arrayDemo() {
        System.out.println("\n========== 数组操作演示 ==========");

        // 1. 数组的创建和初始化
        System.out.println("1. 数组创建和初始化：");

        // 静态初始化 - 直接指定元素值
        int[] staticArray = {85, 92, 76, 88, 95, 82};
        System.out.println("静态初始化数组：" + Arrays.toString(staticArray));

        // 动态初始化 - 指定大小，使用循环赋值
        int[] dynamicArray = new int[6];
        for (int i = 0; i < dynamicArray.length; i++) {
            dynamicArray[i] = (int)(Math.random() * 100);  // 0-99随机数
        }
        System.out.println("动态初始化数组：" + Arrays.toString(dynamicArray));

        // 2. 数组的基本操作
        System.out.println("\n2. 数组基本操作：");

        // 数组长度获取
        System.out.println("数组长度：" + staticArray.length);

        // 数组元素访问和修改
        System.out.println("第一个元素：" + staticArray[0]);
        System.out.println("最后一个元素：" + staticArray[staticArray.length - 1]);

        // 数组遍历 - 普通for循环
        System.out.print("普通for循环遍历：");
        for (int i = 0; i < staticArray.length; i++) {
            System.out.print(staticArray[i] + " ");
        }
        System.out.println();

        // 数组遍历 - 增强for循环（for-each）
        System.out.print("增强for循环遍历：");
        for (int score : staticArray) {  // 更简洁的遍历方式
            System.out.print(score + " ");
        }
        System.out.println();

        // 3. 数组排序和查找
        System.out.println("\n3. 数组排序和查找：");

        // 排序前
        System.out.println("排序前：" + Arrays.toString(staticArray));

        // 数组排序 - 升序
        Arrays.sort(staticArray);
        System.out.println("排序后：" + Arrays.toString(staticArray));

        // 二分查找（需要先排序）
        int searchValue = 88;
        int index = Arrays.binarySearch(staticArray, searchValue);
        System.out.println("查找 " + searchValue + " 的位置：" +
                (index >= 0 ? "索引 " + index : "未找到"));

        // 4. 二维数组演示
        System.out.println("\n4. 二维数组演示：");

        // 二维数组创建和初始化
        int[][] matrix = {
                {90, 85, 92},    // 第1个学生的三门课成绩
                {88, 91, 87},    // 第2个学生的三门课成绩
                {95, 89, 94}     // 第3个学生的三门课成绩
        };

        System.out.println("学生成绩表：");
        System.out.println("学生\\课程\t语文\t数学\t英语\t平均分");

        // 二维数组遍历 - 嵌套循环
        for (int i = 0; i < matrix.length; i++) {          // 遍历行（学生）
            System.out.print("学生" + (i + 1) + "\t");
            int sum = 0;
            for (int j = 0; j < matrix[i].length; j++) {    // 遍历列（课程）
                System.out.print(matrix[i][j] + "\t");
                sum += matrix[i][j];
            }
            double average = (double) sum / matrix[i].length;
            System.out.printf("%.1f\n", average);  // 格式化输出平均分
        }

        // 二维数组的长度属性
        System.out.println("二维数组行数：" + matrix.length);
        System.out.println("第一行列数：" + matrix[0].length);
    }

    /**
     * 5.2 字符串操作演示 - String类方法和StringBuilder
     */
    private static void stringDemo() {
        System.out.println("\n========== 字符串操作演示 ==========");

        // 1. String类基本操作
        System.out.println("1. String类基本操作：");

        String str1 = "Hello World";           // 字符串字面量
        String str2 = new String("Hello");    // 通过构造方法创建

        // 字符串比较 - 重要概念
        System.out.println("字符串比较演示：");
        System.out.println("str1 == str2: " + (str1 == str2));        // false - 比较引用
        System.out.println("str1.equals(str2): " + str1.equals(str2)); // false - 比较内容
        System.out.println("\"Hello\".equals(str2): " + "Hello".equals(str2)); // true

        // 字符串基本属性和方法
        System.out.println("\n字符串基本方法：");
        System.out.println("长度：" + str1.length());
        System.out.println("第一个字符：" + str1.charAt(0));
        System.out.println("转大写：" + str1.toUpperCase());
        System.out.println("转小写：" + str1.toLowerCase());

        // 字符串查找和判断
        System.out.println("\n字符串查找和判断：");
        System.out.println("是否包含'World'：" + str1.contains("World"));
        System.out.println("'World'的位置：" + str1.indexOf("World"));
        System.out.println("是否以'Hello'开头：" + str1.startsWith("Hello"));
        System.out.println("是否以'World'结尾：" + str1.endsWith("World"));

        // 字符串截取和替换
        System.out.println("\n字符串截取和替换：");
        System.out.println("截取前5个字符：" + str1.substring(0, 5));
        System.out.println("从第6个字符开始：" + str1.substring(6));
        System.out.println("替换'World'为'Java'：" + str1.replace("World", "Java"));

        // 字符串分割
        String sentence = "Java,Python,C++,JavaScript";
        String[] languages = sentence.split(",");  // 按逗号分割
        System.out.println("\n分割字符串：" + Arrays.toString(languages));

        // 2. StringBuilder使用 - 高效字符串拼接
        System.out.println("\n2. StringBuilder高效字符串操作：");

        StringBuilder sb = new StringBuilder("Hello");
        System.out.println("初始字符串：" + sb.toString());

        // StringBuilder的常用方法
        sb.append(" World");              // 追加字符串
        System.out.println("追加后：" + sb.toString());

        sb.insert(5, " Java");            // 在指定位置插入
        System.out.println("插入后：" + sb.toString());

        sb.delete(5, 10);                 // 删除指定范围的字符
        System.out.println("删除后：" + sb.toString());

        sb.reverse();                     // 反转字符串
        System.out.println("反转后：" + sb.toString());

        // 3. 字符串性能比较演示
        System.out.println("\n3. 字符串拼接性能比较：");

        int count = 5000;
        long startTime, endTime;

        // String拼接（效率低）
        startTime = System.currentTimeMillis();
        String result1 = "";
        for (int i = 0; i < count; i++) {
            result1 += "a";  // 每次创建新的String对象
        }
        endTime = System.currentTimeMillis();
        System.out.println("String拼接耗时：" + (endTime - startTime) + "ms");

        // StringBuilder拼接（效率高）
        startTime = System.currentTimeMillis();
        StringBuilder builder = new StringBuilder();
        for (int i = 0; i < count; i++) {
            builder.append("a");  // 在现有缓冲区追加
        }
        String result2 = builder.toString();
        endTime = System.currentTimeMillis();
        System.out.println("StringBuilder拼接耗时：" + (endTime - startTime) + "ms");
    }

    /**
     * 5.3 正则表达式演示 - Pattern和Matcher使用
     */
    private static void regexDemo(Scanner scanner) {
        System.out.println("\n========== 正则表达式演示 ==========");

        // 1. 常用正则表达式验证
        System.out.println("1. 常用格式验证：");

        // 手机号验证 - 1开头，第二位3-9，总共11位数字
        String phoneRegex = "^1[3-9]\\d{9}$";
        String[] phones = {"13812345678", "12345678901", "18912345678"};

        System.out.println("手机号验证（正则：" + phoneRegex + "）：");
        for (String phone : phones) {
            boolean isValid = Pattern.matches(phoneRegex, phone);
            System.out.println("  " + phone + " -> " + (isValid ? "有效" : "无效"));
        }

        // 邮箱验证
        String emailRegex = "^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$";
        String[] emails = {"test@example.com", "user123@gmail.com", "invalid.email"};

        System.out.println("\n邮箱验证（正则：" + emailRegex + "）：");
        for (String email : emails) {
            boolean isValid = Pattern.matches(emailRegex, email);
            System.out.println("  " + email + " -> " + (isValid ? "有效" : "无效"));
        }

        // 2. Pattern和Matcher详细使用
        System.out.println("\n2. Pattern和Matcher使用：");

        String text = "联系张三：手机13812345678，邮箱zhang@test.com，李四手机18987654321";

        // 查找所有手机号
        Pattern phonePattern = Pattern.compile("1[3-9]\\d{9}");
        Matcher phoneMatcher = phonePattern.matcher(text);

        System.out.println("原文本：" + text);
        System.out.println("找到的手机号：");
        while (phoneMatcher.find()) {  // find()查找下一个匹配项
            System.out.println("  " + phoneMatcher.group() +
                    " (位置: " + phoneMatcher.start() + "-" + phoneMatcher.end() + ")");
        }

        // 3. 字符串替换和分割
        System.out.println("\n3. 正则表达式替换和分割：");

        // 隐藏手机号中间4位
        String hiddenPhone = text.replaceAll("(1[3-9]\\d)(\\d{4})(\\d{4})", "$1****$3");
        System.out.println("隐藏手机号：" + hiddenPhone);

        // 按多种分隔符分割
        String data = "apple,banana;orange:grape|peach";
        String[] fruits = data.split("[,;:|]");  // 字符类，匹配任意一个分隔符
        System.out.println("分割结果：" + Arrays.toString(fruits));

        // 4. 交互式验证
        System.out.println("\n4. 交互式验证：");
        System.out.print("请输入一个字符串进行格式验证：");
        String input = scanner.nextLine().trim();

        if (!input.isEmpty()) {
            // 验证多种格式
            if (Pattern.matches(phoneRegex, input)) {
                System.out.println("✓ 这是一个有效的手机号");
            } else if (Pattern.matches(emailRegex, input)) {
                System.out.println("✓ 这是一个有效的邮箱");
            } else if (Pattern.matches("\\d{6}", input)) {
                System.out.println("✓ 这是一个邮政编码");
            } else if (Pattern.matches("\\d{4}-\\d{2}-\\d{2}", input)) {
                System.out.println("✓ 这是一个日期格式（YYYY-MM-DD）");
            } else {
                System.out.println("× 未识别的格式");
            }
        }
    }

    /**
     * 综合应用演示 - 学生信息管理
     * 整合数组、字符串、正则表达式的综合应用
     */
    private static void comprehensiveDemo(Scanner scanner) {
        System.out.println("\n========== 综合应用演示 ==========");

        // 模拟学生信息批量处理
        System.out.println("学生信息批量导入验证：");

        // 原始数据（包含格式错误的数据）
        String[] rawData = {
                "张三,20,13812345678,zhang@test.com",      // 正确格式
                "李四,abc,18987654321,li@example.com",     // 年龄错误
                "王五,19,12345678901,wang@test.com",       // 手机号错误
                "赵六,22,13998877665,invalid.email"        // 邮箱错误
        };

        System.out.println("原始数据：");
        for (int i = 0; i < rawData.length; i++) {
            System.out.println((i + 1) + ". " + rawData[i]);
        }

        // 正则表达式定义
        String nameRegex = "^[\\u4e00-\\u9fa5]{2,4}$";     // 2-4个中文字符
        String phoneRegex = "^1[3-9]\\d{9}$";              // 手机号格式
        String emailRegex = "^\\w+@\\w+\\.\\w+$";          // 简化邮箱格式

        System.out.println("\n验证结果：");

        int validCount = 0;  // 有效记录计数

        // 处理每条记录
        for (int i = 0; i < rawData.length; i++) {
            String[] parts = rawData[i].split(",");  // 按逗号分割

            if (parts.length != 4) {
                System.out.println("记录" + (i + 1) + ": 格式错误（字段数量不正确）");
                continue;
            }

            String name = parts[0].trim();
            String ageStr = parts[1].trim();
            String phone = parts[2].trim();
            String email = parts[3].trim();

            // 验证各个字段
            boolean isValid = true;
            StringBuilder errors = new StringBuilder();

            // 验证姓名
            if (!Pattern.matches(nameRegex, name)) {
                errors.append("姓名格式错误; ");
                isValid = false;
            }

            // 验证年龄
            try {
                int age = Integer.parseInt(ageStr);
                if (age < 18 || age > 25) {
                    errors.append("年龄超出范围(18-25); ");
                    isValid = false;
                }
            } catch (NumberFormatException e) {
                errors.append("年龄不是数字; ");
                isValid = false;
            }

            // 验证手机号
            if (!Pattern.matches(phoneRegex, phone)) {
                errors.append("手机号格式错误; ");
                isValid = false;
            }

            // 验证邮箱
            if (!Pattern.matches(emailRegex, email)) {
                errors.append("邮箱格式错误; ");
                isValid = false;
            }

            // 输出验证结果
            if (isValid) {
                // 存储到数组中（演示数组操作）
                if (validCount < studentNames.length) {
                    studentNames[validCount] = name;
                    studentScores[validCount] = Math.random() * 100;  // 随机成绩

                    // 生成三门课程成绩
                    for (int j = 0; j < SUBJECTS.length; j++) {
                        subjectScores[validCount][j] = 60 + Math.random() * 40;  // 60-100分
                    }

                    validCount++;
                }
                System.out.println("记录" + (i + 1) + ": ✓ 有效数据");
            } else {
                System.out.println("记录" + (i + 1) + ": ✗ " + errors.toString());
            }
        }

        // 显示有效数据统计
        currentCount = validCount;
        System.out.println("\n数据导入完成！");
        System.out.println("总记录数：" + rawData.length);
        System.out.println("有效记录数：" + validCount);
        System.out.println("无效记录数：" + (rawData.length - validCount));

        // 显示导入的学生信息
        if (validCount > 0) {
            System.out.println("\n有效学生信息：");
            System.out.printf("%-10s %-10s", "姓名", "平均分");
            for (String subject : SUBJECTS) {
                System.out.printf("%-8s", subject);
            }
            System.out.println();
            System.out.println("-".repeat(50));

            for (int i = 0; i < validCount; i++) {
                System.out.printf("%-10s %-10.1f", studentNames[i], studentScores[i]);
                for (int j = 0; j < SUBJECTS.length; j++) {
                    System.out.printf("%-8.1f", subjectScores[i][j]);
                }
                System.out.println();

            }
        }
    }
}